package org.file5.service.impl;

import java.lang.reflect.Type;
import java.util.Date;

import org.apache.log4j.Logger;
import org.file5.dao.DaoFascade;
import org.file5.domain.Article;
import org.file5.domain.EntityComment;
import org.file5.domain.Person;
import org.file5.service.F5XMPPService;
import org.file5.util.F5XMPPMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.SendResponse;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

@Service("xmppService")
public class F5XMPPServiceImpl implements F5XMPPService {

	private final Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	DaoFascade df;

	@Override
	public void sendArticleCommentNotification(String fromBlogUrl, String commentId) {
		F5XMPPMessage message = new F5XMPPMessage();
		// JID jid = new JID("app-id@appspot.com"); //app-id@appspot.com
		// String msgBody =
		// "Someone has sent you a gift on Example.com. To view: http://example.com/gifts/";

		EntityComment ec = df.getBaseDao().find(EntityComment.class, commentId);
		if (ec != null) {
			Person commentAuthor = df.getBaseDao().find(ec.getAuthorKey());
			Article article = df.getBaseDao().find(ec.getEntityKey());
			Person articleAuthor = null;
			if (article != null) {
				articleAuthor = df.getBaseDao().find(article.getAuthorKey());
			}
			if (commentAuthor != null &&commentAuthor.getBlogJid()!=null&&!commentAuthor.getBlogJid().isEmpty() && articleAuthor != null) {
				message.setType(F5XMPPMessage.TYPE.COMMENT_NOTIFY);

				message.getData().put("fromBlogUrl", fromBlogUrl);

				message.getData().put("commentUid", ec.getUid());
				message.getData().put("commentContent", ec.getComment());
				message.getData().put("commentDate", ec.getCreated());
				message.getData().put("commentAuthorUid", commentAuthor.getUid());
				message.getData().put("commentAuthorEmail", commentAuthor.getEmail());
				message.getData().put("commentAuthorBlogUrl", commentAuthor.getBlogUrl());

				message.getData().put("articleUid", article.getUid());
				message.getData().put("articleName", article.getName());
				message.getData().put("articleAuthorUid", articleAuthor.getUid());
				message.getData().put("articleAuthorEmail", articleAuthor.getEmail());
				message.getData().put("articleAuthorBlogUrl", articleAuthor.getBlogUrl());

				EntityComment pec = df.getBaseDao().find(ec.getParentCommentKey());
				Person pcommentAuthor = null;
				if (pec != null) {
					pcommentAuthor = df.getBaseDao().find(pec.getAuthorKey());
					// continue use the message,append the parent comment
					// information
					message.getData().put("parentCommentUid", pec.getUid());
					message.getData().put("parentCommentUid", pec.getUid());
					message.getData().put("parentCommentContent", pec.getComment());
					message.getData().put("parentCommentDate", pec.getLastUpdated());
					message.getData().put("parentCommentAuthorUid", pcommentAuthor.getUid());
					message.getData().put("parentCommentAuthorEmail", pcommentAuthor.getEmail());
					message.getData().put("parentCommentAuthorBlogUrl", pcommentAuthor.getBlogUrl());
				}

				Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
				Type type = new TypeToken<F5XMPPMessage>() {
				}.getType();
				String jsonBody = gson.toJson(message, type);

				String jidStr = commentAuthor.getBlogJid();
				sendMessage(jidStr, jsonBody);

				// notification for parent comment
				if (pec != null && pcommentAuthor != null&&pcommentAuthor.getBlogJid()!=null&&!pcommentAuthor.getBlogJid().isEmpty()) {
					sendMessage(pcommentAuthor.getBlogJid(), jsonBody);
				}
			}
		}

	}

	private void sendMessage(String blogJid, String messageBody) {
		JID jid = new JID(blogJid);
		Message msg = new MessageBuilder().withRecipientJids(jid).withBody(messageBody).build();

		boolean messageSent = false;
		XMPPService xmpp = XMPPServiceFactory.getXMPPService();
		if (xmpp.getPresence(jid).isAvailable()) {
			SendResponse status = xmpp.sendMessage(msg);
			messageSent = (status.getStatusMap().get(jid) == SendResponse.Status.SUCCESS);
		}

		if (!messageSent) {
			// Send an email message instead...
		}

	}

	@Override
	public void receiveArticleCommentNotification(String message) {
		// TODO Auto-generated method stub
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

		Type typeedb = new TypeToken<F5XMPPMessage>() {
		}.getType();

		F5XMPPMessage f5Message = gson.fromJson(message, typeedb);
		// TODO save related information
		// message.getData().put("fromBlogUrl", fromBlogUrl);
		String fromBlogUrl = (String) f5Message.getData().get("fromBlogUrl");
		//
		// message.getData().put("commentUid", ec.getUid());
		// message.getData().put("commentContent", ec.getComment());
		// message.getData().put("commentDate", ec.getLastUpdated());
		// message.getData().put("commentAuthorUid", commentAuthor.getUid());
		// message.getData().put("commentAuthorEmail",
		// commentAuthor.getEmail());
		// message.getData().put("commentAuthorBlogUrl",
		// commentAuthor.getBlogUrl());
		String commentUid = (String) f5Message.getData().get("commentUid");
		String commentContent = (String) f5Message.getData().get("commentContent");
		Date commentDate = (Date) f5Message.getData().get("commentDate");
		String commentAuthorUid = (String) f5Message.getData().get("commentAuthorUid");
		String commentAuthorEmail = (String) f5Message.getData().get("commentAuthorEmail");
		String commentAuthorBlogUrl = (String) f5Message.getData().get("commentAuthorBlogUrl");
		//
		// message.getData().put("articleUid", article.getUid());
		// message.getData().put("articleName", article.getName());
		// message.getData().put("articleAuthorUid", articleAuthor.getUid());
		// message.getData().put("articleAuthorEmail",
		// articleAuthor.getEmail());
		// message.getData().put("articleAuthorBlogUrl",
		// articleAuthor.getBlogUrl());

	}

}
